﻿using Microsoft.AspNetCore.DataProtection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace IdentityDemo.CookiesJwt
{
    /// <summary>
    /// 对信息进行加密
    /// </summary>
    public class DataJwtProtector : IDataProtector
    {
        public const string type = "JWT";

        public string alg = "HS256";

        public const string secret = "this is password";

        private string Header
        {
            get
            {
                return $"{{\"type\":\"{type}\",\"alg\":\"{alg}\"}}";
            }
        }

        public IDataProtector CreateProtector(string purpose)
        {
            throw new NotImplementedException();
        }

        public byte[] Protect(byte[] plaintext)
        {
            var headerBase64 = Convert.ToBase64String(Encoding.Default.GetBytes(Header));
            var playloadBase64 = Convert.ToBase64String(plaintext);
            var signature = ComputeSecurity(plaintext);
            var jwt = $"{headerBase64}.{playloadBase64}.{signature}";
            return Encoding.Default.GetBytes(jwt);
        }

        public byte[] Unprotect(byte[] protectedData)
        {
            var jwt = Encoding.Default.GetString(protectedData);
            var jwtSplits = jwt.Split('.');
            var headerBase64 = jwtSplits[0];
            var playloadBase64 = jwtSplits[1];
            var signature = jwtSplits[2];
            var playload = Convert.FromBase64String(playloadBase64);
            var validataSignature= ComputeSecurity(playload);
            if (signature != validataSignature)
            {
                throw new SecurityTokenValidationException();
            }
            return playload;
        }

        private string ComputeSecurity(byte[] dataBytes)
        {
            var keyByte = Encoding.Default.GetBytes(secret);
            using (var hmac = HMAC.Create("HMACSHA256"))
            {
                hmac.Key = dataBytes;
                byte[] hashData = hmac.ComputeHash(dataBytes);
                return Convert.ToBase64String(hashData);
            }
            SecurityAlgorithms.HmacSha256.ToString();
        }
    }
}
